<?php

class Db_Query {
	const PATERN_SELECT = "select";
	const PATERN_DELETE = "delete";
	const PATERN_UPDATE = "update";
	const PATERN_INSERT = "insert";

	private $_select = array("*" => "*");
	private $_from = array();
	private $_where = array();
	private $_order = array();
	private $_limit = array();
	private $_with = array();
	private $_patern = "select";

	public function __construct (array $data = array()) {
		foreach ($data as $k => $v) {
			$this->$k = $v;
		}
	}

	public function select (array $select = array("*" => "*")) {
		foreach ($select as $k => $v) {
			$this->_select[$k] = $v;
		}
		return $this;
	}

	public function from ($from) {
		$this->_from[$from] = $from;
		return $this;
	}
	
	public function where($where){
		$this->_where[$where] = $where;
		return $this;
	}

	public function limit ($limit) {
		if (!is_array($limit)) $limit = array(0 => $limit);
		$this->_limit = $limit;
		return $this;
	}
	
	public function with($with){
		$this->_with[$with] = $with;
	}

	public function exec () {
		$query = $this->buildQuery();
		return App::inst()->db()->q($query);
	}

	public function fetchArray () {
		$result = $this->exec();
		$return = array();
		while ($row = mysql_fetch_assoc($result)) {
			$return[] = $row;
		}

		return $return;
	}

	public function collection ($model) {
		$result = $this->exec();
		$return = new Db_Collection();
		while ($row = mysql_fetch_assoc($result)) {
			$item = Db::model($model, Db_Record::EVENT_UPDATE);
			$item->fromArray($row);
			$return[] = $item;
		}

		return $return;
	}

	public function buildQuery () {
		switch ($this->_patern) {
			case self::PATERN_SELECT:
				return $this->_buildQuerySelect();
				break;
		}
	}

	private function _buildQuerySelect () {
		$q = "
SELECT
	" . join(', ', $this->_select) . "
FROM
	" . join(', ', $this->_from) . "
";
		$join = "";
		$where = "";
		$order = "";
		$limit = "";

		if (count($this->_where)) {
			$where = "WHERE " . join(' AND ', $this->_where);
		}

		if (count($this->_order)) {
			$order = "ORDER BY " . join(', ', $this->_order);
		}

		if (count($this->_limit)) {
			$limit = "LIMIT " . join(', ', $this->_limit);
		}
		
		if(count($this->_with)){
			foreach($this->_with as $w){
				$j = new Db_Join_Left();
				$j->fromRelation($w);
			}
		}

		$q .= "$join $where $order $limit";

		return $q;
	}

}